#include "applyfriend.h"
#include <QJsonDocument>
#include "clickedoncelabel.h"
#include "global.h"
#include "tcpmgr.h"
#include "ui_applyfriend.h"
#include "usermgr.h"
ApplyFriend::ApplyFriend(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ApplyFriend)
{
    ui->setupUi(this);
    this->setObjectName("ApplyFriend");
    this->setModal(true);
    ui->lb_edit->setPlaceholderText("搜索、添加标签");
    ui->apply_edit->setPlaceholderText("好友申请");
    ui->note_edit->setPlaceholderText("备注");
    ui->tip_msg->setText(ADD_PREFIX);
    ui->tip_msg->adjustSize();
    ui->lb_edit->setFixedHeight(30);
    ui->lb_edit->setMaxLength(20);
    ui->lb_edit->move(2, 2);
    ui->input_lb_wid->hide();
    ui->combine_wid->adjustSize();
    _optionaLabelPoint = QPoint(2, 2);
    _selectedLabelPoint = QPoint(2, 2);
    ui->tip_wid->move(2, 2);
    _tipData = {"同学",
                "家人",
                "菜鸟教程",
                "Rust 程序设计",
                "微信读书",
                "C++基础教程",
                "动手学python",
                "java核心编程",
                "c++对象基础"};
    connect(ui->more_lb, &ClickedOnceLabel::sig_clicked, this, &ApplyFriend::slot_showMoreLabel);
    connect(ui->lb_edit, &QLineEdit::returnPressed, this, &ApplyFriend::slot_labelEnter);
    connect(ui->lb_edit, &QLineEdit::textChanged, this, &ApplyFriend::slot_labelTextChange);
    connect(ui->lb_edit, &QLineEdit::editingFinished, this, &ApplyFriend::slot_labelEditFinished);
    connect(ui->tip_lb, &ClickedOnceLabel::sig_clicked, this, &ApplyFriend::slot_addLabelByClickTip);
    ui->lb_edit->setFixedWidth(361 - ui->lb_edit->x());

    InitTipLbs();
}

ApplyFriend::~ApplyFriend()
{
    delete ui;
}

void ApplyFriend::InitTipLbs()
{
    for (int i = 0; i < _tipData.size(); ++i) {
        if (i > 5) {
            return;
        }
        addOptionalLabel(_tipData[i]);
        // 所有标签都已经加载
        if (i == _tipData.size() - 1) {
            ui->more_lb->hide();
        }
    }
}

void ApplyFriend::setSearchInfo(std::shared_ptr<SearchInfo> si)
{
    _si = si;
}

bool ApplyFriend::eventFilter(QObject *watched, QEvent *event)
{
    return QDialog::eventFilter(watched, event);
}

void ApplyFriend::resetLabel() {}

void ApplyFriend::addSelectedLabel(QString label)
{
    // 标签已存在
    for (int i = 0; i < _selectedLabels.size(); ++i) {
        if (_selectedLabels[i]->text() == label)
            return;
    }
    auto lb = std::make_shared<FriendLabel>(ui->combine_wid);
    lb->setText(label);
    lb->setObjectName("FriendLabel");
    connect(lb.get(), &FriendLabel::sig_close, this, &ApplyFriend::slot_removeFriendLabel);
    lb->adjustSize();
    int maxWidth = ui->combine_wid->width();
    // 计算位置
    if (_selectedLabelPoint.x() + lb->width() + 2 > maxWidth) {
        _selectedLabelPoint.setY(_selectedLabelPoint.y() + lb->height() + 10);
        _selectedLabelPoint.setX(2);
    }
    lb->move(_selectedLabelPoint);
    lb->show();
    _selectedLabels.push_back(lb);
    // 更新 下一个标签的位置
    _selectedLabelPoint.setX(_selectedLabelPoint.x() + lb->width() + 2);
    // 计算lb_edit的最新位置
    ui->lb_edit->setFixedWidth(30);
    if (_selectedLabelPoint.x() + ui->lb_edit->rect().width() > ui->combine_wid->width()) {
        ui->lb_edit->move(2, _selectedLabelPoint.y() + lb->height() + 10);
    } else {
        ui->lb_edit->move(_selectedLabelPoint);
    }
    ui->lb_edit->setFixedWidth(maxWidth - ui->lb_edit->x());
    int combine_height = ui->combine_wid->pos().y() + ui->combine_wid->height();
    int lb_edit_height = ui->lb_edit->pos().y() + ui->lb_edit->height();
    if (lb_edit_height + 10 > combine_height) {
        ui->combine_wid->setFixedHeight(ui->combine_wid->height() + ui->lb_edit->rect().height());
    }
}

void ApplyFriend::addOptionalLabel(QString label)
{
    // 生成ClickedLabel
    auto lb = std::make_shared<ClickedLabel>(ui->lb_list);
    lb->setObjectName("tipslb");
    lb->setText(label);
    // 如果标签被选中
    connect(lb.get(), &ClickedLabel::sig_del, this, &ApplyFriend::slot_delLabel);
    connect(lb.get(), &ClickedLabel::sig_changeState, this, &ApplyFriend::slot_labelStateChange);

    QFontMetrics ft(lb->font());
    QRect textRect = ft.boundingRect(label);
    // 文本宽度
    int textWidth = textRect.width();
    // 文本高度
    int textHeight = textRect.height();
    if (_optionaLabelPoint.x() + textWidth + TIP_OFFSET + 3 > ui->lb_list->width()) {
        // 换行
        _optionaLabelPoint.setY(_optionaLabelPoint.y() + textHeight + 10);
        _optionaLabelPoint.setX(2);
    }
    // 添加标签
    lb->move(_optionaLabelPoint);
    lb->show();
    _optionalLabels.push_back(lb);
    _optionaLabelPoint.setX(lb->pos().x() + lb->width() + 3);
    _optionaLabelPoint.setY(lb->pos().y());
    // 修改滚送区域高度
    if (_optionaLabelPoint.y() + TIP_OFFSET > ui->scrollContent->height()) {
        ui->scrollContent->setFixedHeight(_optionaLabelPoint.y() + lb->height() + 2);
    }
}

void ApplyFriend::removeOptionalLabel(QString text)
{
    // 从待选择列表中删除元素
    auto it = std::find(_tipData.begin(), _tipData.end(), text);
    if (it != _tipData.end()) {
        return;
    }
    int pos = -1;
    for (int i = 0; i < _optionalLabels.size(); ++i) {
        if (_optionalLabels[i]->text() == text) {
            pos = i;
            break;
        }
    }
    if (pos == -1) {
        return;
    }
    _optionalLabels[pos]->hide();
    QPoint point = _optionalLabels[pos]->pos();
    _optionalLabels.remove(pos);
    // 遍历后面的元素，依次把元素往前移动
    for (int i = pos; i < _optionalLabels.size(); i++) {
        // 移动元素
        if (point.x() + _optionalLabels[i]->width() + 2 > ui->lb_list->width()) {
            // 换行
            point.setY(point.y() + _optionalLabels[i]->height() + 2);
            point.setX(2);
        }
        if (_optionalLabels[i]->x() == point.x()) {
            return;
        }
        _optionalLabels[i]->move(point);
        // 更新可插入点坐标 point
        point.setX(_optionalLabels[i]->x() + _optionalLabels[i]->width() + 2);
    }
    // 修改 _tipCurPoint
    _optionaLabelPoint.setX(point.x());
    _optionaLabelPoint.setY(point.y());
    if (_selectedLabels.size() > 0) {
        ui->combine_wid->setFixedHeight(ui->lb_edit->y() + ui->lb_edit->height());
    } else {
        ui->combine_wid->setFixedHeight(30);
    }
}

void ApplyFriend::removeSelectedLabel(QString label)
{
    // 删除从已选择元素列表中删除对应元素
    int pos = -1;
    for (int i = 0; i < _selectedLabels.size(); i++) {
        if (_selectedLabels[i]->text() == label) {
            pos = i;
            break;
        }
    }
    if (pos == -1) {
        return;
    }
    _selectedLabels[pos]->hide();
    QPoint point = _selectedLabels[pos]->pos();
    _selectedLabels.remove(pos);
    int maxWidth = ui->combine_wid->width();
    // 遍历后面的元素，依次把元素往前移动
    for (int i = pos; i < _selectedLabels.size(); i++) {
        // 移动元素
        if (point.x() + _selectedLabels[i]->width() > maxWidth) {
            // 换行
            point.setY(point.y() + _selectedLabels[i]->height());
            point.setX(2);
        }
        _selectedLabels[i]->move(point);
        // 更新可插入点坐标 point
        point.setX(_selectedLabels[i]->x() + _selectedLabels[i]->width() + 2);
    }
    // 修改 _labelPoint
    _selectedLabelPoint.setX(point.x());
    _selectedLabelPoint.setY(point.y());
    // 移动lb edit的位置
    ui->lb_edit->setFixedWidth(30);
    if (_selectedLabelPoint.x() + ui->lb_edit->width() < maxWidth) {
        ui->lb_edit->move(_selectedLabelPoint);
    } else {
        if (ui->lb_edit->x() != 2) {
            ui->lb_edit->move(2, ui->lb_edit->y());
        }
    }
    ui->lb_edit->setFixedWidth(maxWidth - ui->lb_edit->x());
    ui->combine_wid->adjustSize();
}

void ApplyFriend::slot_showMoreLabel()
{
    // 将所有标签添加至可选标签处
    if (!_tipData.isEmpty()) {
        foreach (const QString &label, _tipData) {
            addOptionalLabel(label);
        }
    }
    ui->more_lb->hide();
}

void ApplyFriend::slot_labelEnter()
{
    QString label = ui->lb_edit->text();
    if (label.isEmpty()) {
        return;
    }
    // 添加标签
    addSelectedLabel(label);
    ui->input_lb_wid->hide();
    ui->lb_edit->clear();
    // 判断展示栏是否存在该标签
    for (int i = 0; i < _optionalLabels.size(); ++i) {
        if (_optionalLabels[i]->text() == label)
            return;
    }
    // 不存在 则添加标签
    addOptionalLabel(label);
}

void ApplyFriend::slot_removeFriendLabel(QString text)
{
    // 删除从已选择元素列表中删除对应元素
    removeSelectedLabel(text);
    // 删除从待选择元素列表中删除对应元素
    removeOptionalLabel(text);
}

void ApplyFriend::slot_delLabel(QString text)
{
    slot_removeFriendLabel(text);
}

void ApplyFriend::slot_labelTextChange(const QString &text)
{
    if (text.isEmpty()) {
        ui->tip_lb->clear();
        ui->input_lb_wid->hide();
        return;
    }
    auto iter = std::find(_tipData.begin(), _tipData.end(), text);
    if (iter == _tipData.end()) {
        ui->tip_lb->setText(text);
        ui->input_lb_wid->show();
        return;
    }
    ui->tip_lb->setText(text);
    ui->tip_wid->setFixedWidth(361);
    ui->input_lb_wid->show();
}

void ApplyFriend::slot_labelEditFinished()
{
    ui->input_lb_wid->hide();
}

void ApplyFriend::slot_addLabelByClickTip(QString text)
{
    QString label = text.trimmed();
    if (label.isEmpty()) {
        return;
    }
    ui->lb_edit->clear();
    addSelectedLabel(label);
    auto iter = std::find(_tipData.begin(), _tipData.end(), label);
    if (iter == _tipData.end()) {
        _tipData.push_back(label);
    }

    for (int i = 0; i < _optionalLabels.size(); ++i) {
        if (_optionalLabels[i]->text() == text)
            _optionalLabels[i]->setSelected();
        return;
    }
    // 标签展示栏添加标签
    addOptionalLabel(label);
}

void ApplyFriend::slot_applySure()
{
    // 发送添加请求
    QJsonObject jsonObj;
    // 自己的uid
    int uid = UserMgr::GetInstance()->GetUid();
    // 好友申请
    QString applyDetail = ui->apply_edit->toPlainText().trimmed();
    if (applyDetail.isEmpty()) {
        applyDetail = ui->apply_edit->placeholderText();
    }
    // 备注
    QString remark = ui->note_edit->text().trimmed();
    if (remark.isEmpty()) {
        remark = ui->note_edit->placeholderText();
    }
    // 对方uid
    int toUid = _si->_uid;
    // 发送添加好友请求
    // 标签暂时不处理
    jsonObj["uid"] = uid;
    jsonObj["apply"] = applyDetail;
    jsonObj["remark"] = remark;
    jsonObj["touid"] = toUid;

    QJsonDocument doc(jsonObj);
    QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
    //发送添加好友请求
    emit TcpMgr::GetInstance()->sig_send_data(ReqId::ID_ADD_FRIEND_REQ, jsonData);
    qDebug() << "send add friend request.\n";
    // 关闭当前页面
    deleteLater();
}

void ApplyFriend::slot_applyCancal()
{
    this->hide();
    this->deleteLater();
}

void ApplyFriend::slot_labelStateChange()
{
    ClickedLabel *lb = static_cast<ClickedLabel *>(sender());
    ClickedLabel::State state = lb->getState();
    // 从已选择标签中移除
    if (state == ClickedLabel::Selected) {
        removeSelectedLabel(lb->text());
        lb->setNoSelected();
    }
    if (state == ClickedLabel::NoSelected) {
        addSelectedLabel(lb->text());
        lb->setSelected();
    }
}

void ApplyFriend::on_sure_btn_clicked()
{
    slot_applySure();
}

void ApplyFriend::on_cancel_btn_clicked()
{
    slot_applyCancal();
}
